package login

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
	"github.com/mojocn/base64Captcha"
	"handitem/xxb-gin-web/commons/jwtgo"
	"handitem/xxb-gin-web/commons/response"
	"handitem/xxb-gin-web/model/sys"
	"handitem/xxb-gin-web/utils"
	"time"
)

// 登录业务
type LoginApi struct{}

// 1: 定义验证的store --默认是存储在go内存中
var store = base64Captcha.DefaultMemStore

// 登录的接口处理
func (api *LoginApi) ToLogined(c *gin.Context) {
	// 1：获取用户在页面上输入的账号和密码开始和数据库里数据进行校验

	//定义前端传过来的请求参数
	type LoginParam struct {
		Account  string
		Password string
		Code     string
		CodeId   string
	}

	//参数的绑定
	param := LoginParam{}
	err2 := c.ShouldBindJSON(&param)

	if err2 != nil {
		response.Fail(60002, "参数绑定有误", c)
		return
	}

	if len(param.CodeId) == 0 {
		response.Fail(60002, "获取验证码失败", c)
		return
	}
	if len(param.Code) == 0 {
		response.Fail(60002, "请输入验证码", c)
		return
	}
	// 开始校验验证码是否正确
	verify := store.Verify(param.CodeId, param.Code, true)
	if !verify {
		response.Fail(60002, "你输入的验证码有误!!", c)
		return
	}

	inputAccount := param.Account
	inputPassword := param.Password

	if len(inputAccount) == 0 {
		response.Fail(60002, "请输入账号", c)
		return
	}

	if len(inputPassword) == 0 {
		response.Fail(60002, "请输入密码", c)
		return
	}

	dbUser, err := sysUserService.GetUserByAccount(inputAccount)
	if err != nil {
		response.Fail(60002, "你输入的账号和密码有误", c)
		return
	}

	// 这个时候就判断用户输入密码和数据库的密码是否一致
	if dbUser != nil && dbUser.Password == inputPassword {
		//根据id获取用户角色
		roles := make([]map[string]any, 2)
		roles[0] = map[string]any{"id": 1, "name": "超级管理员"}
		roles[1] = map[string]any{"id": 2, "name": "财务"}
		//根据用户id获取角色权限
		permissions := make([]map[string]any, 2)
		permissions[0] = map[string]any{"id": 2001, "name": "保护用户"}
		permissions[1] = map[string]any{"id": 2002, "name": "删除用户"}
		token := api.generateToken(c, dbUser)
		response.Ok(map[string]any{"user": dbUser, "token": token, "roles": roles, "permissions": permissions}, c)
	} else {
		response.Fail(60002, "你输入的账号和密码有误", c)
		return
	}
}

func (api *LoginApi) generateToken(c *gin.Context, dbUser *sys.SysUser) string {

	// 设置token续期的缓冲时间
	bf, _ := utils.ParseDuration("1d")
	ep, _ := utils.ParseDuration("7d")

	myJwt := jwtgo.NewJWT()
	token, err2 := myJwt.CreateToken(jwtgo.CustomClaims{
		dbUser.ID,
		dbUser.Username,
		int64(bf / time.Second), //缓冲时间
		jwt.StandardClaims{
			Audience:  "KSD",                                    // 受众
			Issuer:    "KSD-ADMIN",                              // 签发者
			IssuedAt:  time.Now().Unix(),                        // 签发时间
			NotBefore: time.Now().Add(-10 * time.Second).Unix(), // 生效时间
			ExpiresAt: time.Now().Add(ep).Unix(),                // 过期时间
		},
	})
	fmt.Println("当前时间是：", time.Now().Unix())
	fmt.Println("签发时间：" + time.Now().Format("2006-01-02 15:04:05"))
	fmt.Println("生效时间：" + time.Now().Add(-10*time.Second).Format("2006-01-02 15:04:05"))
	fmt.Println("过期时间：" + time.Now().Add(ep).Format("2006-01-02 15:04:05"))
	if err2 != nil {
		response.Fail(60002, "登录失败，token颁发不成功!", c)
	}
	return token
}
